package com.coocaa.app.lib.cleaner.scanner.impl;

import android.content.Context;

import com.coocaa.app.lib.cleaner.mgr.DataHolder;
import com.coocaa.app.lib.cleaner.scanner.AbstractScanner;
import com.coocaa.app.lib.cleaner.scanner.ScanRunner;
import com.coocaa.app.lib.cleaner.scanner.config.ConfigManagerFactory;
import com.coocaa.app.lib.cleaner.scanner.packages.PackagesScanner;
import com.coocaa.app.lib.cleaner.scanner.scannerapk.ApkScanner;
import com.coocaa.app.lib.cleaner.scanner.scannerother.OtherScanner;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by lu on 17-4-12.
 */

public class ScanRunnerImpl implements ScanRunner {
    private ScanRunnerListener listener;

    private List<AbstractScanner> scanners;
    private int scannersCount = 0;

    private class Runner implements Runnable {
        private AbstractScanner runnable;

        public Runner(AbstractScanner runnable) {
            this.runnable = runnable;
        }

        @Override
        public void run() {
            try {
                runnable.run();
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (listener != null)
                listener.onScanEnd(runnable);
            synchronized (ScanRunnerImpl.this) {
                scannersCount -= 1;
                if (scannersCount == 0) {
                    if (listener != null)
                        listener.onScanAllEnd();
                }
            }
        }
    }

    private ExecutorService executor = null;
    private Context mContext;

    public ScanRunnerImpl() {
    }

    @Override
    public void init(Context context) {
        this.mContext = context.getApplicationContext();
        ConfigManagerFactory.factory.instance().init(mContext);
        scanners = new ArrayList<AbstractScanner>();
        scanners.add(new PackagesScanner());
        scanners.add(new ApkScanner());
        scanners.add(new OtherScanner());
    }

    @Override
    public boolean start(ScanRunnerListener listener, DataHolder holder) {
        this.listener = listener;
        synchronized (this) {
            if (scannersCount != 0)
                return false;
            for (AbstractScanner s : scanners)
                s.setDataHolder(mContext, holder);
            scannersCount = this.scanners.size();
            if (executor != null)
                executor.shutdown();
            executor = Executors.newFixedThreadPool(scanners.size());
            if (listener != null)
                listener.onScanStart();
            for (AbstractScanner s : scanners)
                executor.execute(new Runner(s));
            return true;
        }
    }

    @Override
    public void stop() {
        if (scanners != null) {
            for (AbstractScanner s : scanners)
                s.stop();
        }
    }
}
